<template>
  <teleport to="body">
    <transition name="fade">
      <div
        ref="resultRef"
        v-if="modelValue"
        class="searchResult"
        v-draggable="{ callback: closeInfoCard }"
      >
        <SvgIcon icon-class="subtract" class="searchResult-close" @click="closeResult" />
        <div id="header" class="searchResult-header">
          <span>搜索结果</span>
        </div>
        <el-scrollbar :max-height="230">
          <ul ref="resultListRef">
            <li
              v-for="item in datas"
              :key="item.userId"
              class="searchResult-item"
              @click="handleToUserInfo(item)"
            >
              <img class="searchResult-item__img" :src="item.avatar" alt="" />
              <span>{{ item.nickName }}</span>
            </li>
          </ul></el-scrollbar
        >
        <info-card
          v-model="showInfoCard"
          :trigger-ele="resultListRef"
          :userData="userInfo"
        >
          <template #footer>
            <div class="person-dynamic" @click="showDynamic = true">
              个人动态
              <SvgIcon icon-class="rightArrow" popper-class="rightArrowIcon" />
            </div>
            <el-button
              v-if="userInfo.isFriend"
              class="opeaBut"
              type="primary"
              :disabled="isSendLoading"
              :loading="isSendLoading"
              @click="startSend(userInfo.userId)"
              ><template #loading><Loading /></template>发消息</el-button
            >
            <el-button
              v-else-if="user.userId !== userInfo.userId"
              class="opeaBut"
              type="primary"
              @click="showDialog = true"
              >加好友</el-button
            >
          </template>
        </info-card>
      </div> </transition
    ><apply-dialog
      v-model="showDialog"
      :nick-name="userInfo.nickName"
      :user-id="userInfo.userId"
    ></apply-dialog
  ></teleport>
  <dynamic
    v-model="showDynamic"
    :usr-info="userInfo"
    :is-friend="userInfo.userId === user.userId ? true : userInfo.isFriend"
    :is-self="userInfo.userId === user.userId"
  ></dynamic>
</template>

<script lang="ts" setup>
import { ref, onMounted, onBeforeUnmount, watch } from "vue";
import vDraggable from "@/directives/draggable";
import infoCard from "../infoCard.vue";
import { useUserPinia } from "@/pinia/user";
import { storeToRefs } from "pinia";
import { useMessagePinia } from "@/pinia/messages";
import applyDialog from "./applyDialog.vue";
import { useRouter } from "vue-router";
import { ElMessage } from "element-plus";
import dynamic from "@/components/dynamic/index.vue";

const props = defineProps<{
  datas: Array<User & { isFriend: boolean; bkImg: string }>;
  fatherEle: HTMLDivElement;
  modelValue: boolean;
}>();
const emits = defineEmits<{
  (e: "update:modelValue", show: boolean): void;
}>();

const router = useRouter();
const { user } = storeToRefs(useUserPinia());
const messageStore = useMessagePinia();

/**
 * 给该组件一个ref属性
 */
const resultRef = ref<HTMLDivElement>(document.createElement("div"));
/**
 * 给列表ul元素一个ref属性
 */
const resultListRef = ref<HTMLUListElement>(document.createElement("ul"));
/**
 * 设置该组件距离视图的上边界距离
 */
const setTop = () => {
  setTimeout(() => {
    if (resultRef.value) {
      const rect = props.fatherEle.getBoundingClientRect();
      const fatherTop: number = rect.y;
      const fatherLeft: number = rect.left;
      const top: number = +resultRef.value?.style.top.replace("px", "");
      if (!top || (top && top < fatherTop + 50))
        resultRef.value.style.cssText += `top: ${fatherTop + scrollY + 55}px;`;
      resultRef.value.style.cssText += `display: block;left: ${fatherLeft}px;`;
    }
  }, 100);
};

watch(
  () => props.modelValue,
  (show: boolean) => {
    if (show) setTop();
  }
);

onMounted(() => window.addEventListener("resize", setTop));
onBeforeUnmount(() => window.removeEventListener("resize", setTop));

/**
 * 是否显示个人信息框
 */
const showInfoCard = ref<boolean>(false);
const closeInfoCard = () => (showInfoCard.value = false);

/**
 * 当前用户需要查询的用户信息
 */
const userInfo = ref<User & { isFriend: boolean; bkImg: string }>({
  nickName: "",
  remark: "",
  userId: "",
  sex: "男",
  age: 0,
  address: "",
  avatar: "",
  isFriend: false,
  signature: "",
  bkImg: "",
});

// 更改用户查询的其他用户信息
const handleToUserInfo = (user: User & { isFriend: boolean; bkImg: string }) => {
  userInfo.value = user;
  if (!showInfoCard.value) showInfoCard.value = true;
  new Image().src = user.bkImg;
};

// 关闭搜索结果
const closeResult = () => {
  if (showInfoCard.value) showInfoCard.value = false;
  emits("update:modelValue", false);
};

/**
 * 是否显示申请添加朋友的对话框
 */
const showDialog = ref<boolean>(false);
/**
 * 是否正在给好友发送消息
 */
const isSendLoading = ref<boolean>(false);

// 开始给好友发送消息
const startSend = (userId: string) => {
  if (messageStore.chatList.has(userId)) {
    showInfoCard.value = false;
    emits("update:modelValue", false);
    router.replace({ path: "/chatRecord", query: { userId } });
  } else {
    isSendLoading.value = true;
    messageStore
      .readySendMessage({
        selfId: user.value.userId,
        otherId: userId,
      })
      .then((code: number) => {
        isSendLoading.value = false;
        if (code === 1) {
          showInfoCard.value = false;
          emits("update:modelValue", false);
          router.replace({ path: "/chatRecord", query: { userId } });
        } else if (code === -2)
          ElMessage({
            type: "error",
            message: "操作失败，对方和自己不是好友关系",
            duration: 1500,
          });
        else
          ElMessage({
            type: "error",
            message: "跳转失败",
            duration: 1500,
          });
      })
      .catch(() => {
        isSendLoading.value = false;
        ElMessage({
          type: "error",
          message: "跳转失败",
          duration: 1500,
        });
      });
  }
};

/**
 * 是否显示个人动态
 */
const showDynamic = ref<boolean>(false);
</script>

<style lang="scss" scoped>
.fade {
  @include fade(0.15s, ease);
}

.searchResult {
  position: absolute;
  display: none;
  width: 330px;
  max-height: 288px;
  border-radius: 2px;
  background-color: #fff;
  box-shadow: 0px 12px 32px 4px rgba(0, 0, 0, 0.04), 0px 8px 20px rgba(0, 0, 0, 0.08);
  z-index: 99;
  padding-bottom: 8px;

  &:hover {
    .searchResult-close {
      display: block;
    }
  }

  &-header {
    height: 50px;
    line-height: 50px;
    padding: 0 20px;
    color: $dimFontCor;
    font-size: 14px;
    cursor: move;
    @include noselect();
  }

  &-item {
    cursor: pointer;
    padding: 8px 20px;
    transition: background-color 0.2s;

    &:hover {
      background-color: rgba(154, 152, 152, 0.114);
    }

    &__img {
      @include setWidHei(40px, 40px);
      border-radius: 50%;
      object-fit: cover;
      vertical-align: middle;
      margin-right: 15px;
    }
  }

  &-close {
    position: absolute;
    right: 10px;
    top: 8px;
    cursor: pointer;
    font-size: 18px;
    display: none;

    &:hover {
      color: #409eff;
    }
  }

  .person-dynamic {
    position: relative;
    font-size: 13px;
    color: #333;
    transition: color 0.3s;
    cursor: pointer;
    text-align: left;

    &:hover {
      color: #52a8fd;
    }

    .rightArrowIcon {
      position: absolute;
      right: 0;
      top: 50%;
      transform: translateY(-50%);
    }
  }

  .opeaBut {
    margin-top: 20px;
    width: 100%;
  }
}
</style>
